﻿using System;
using System.Web;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Threading;
using System.Security.Cryptography;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;

namespace ChestPainCenterSystem.Utils
{
    public class WebUtils {

        #region 获取网站的真实路径
        /// <summary>
        /// 获取网站的真实路径
        /// </summary>
        /// <returns></returns>
        public static string GetWebSiteReallyPath() {
            string path = HttpContext.Current.Request.Path;
            if (path.LastIndexOf("/") != path.IndexOf("/")) {
                path = path.Substring(path.IndexOf("/"), path.LastIndexOf("/") + 1);
            } else {
                path = "/";
            }
            return path;

        }
        #endregion

        #region 获取当前绝对路径
        /// <summary>
        /// 获取当前绝对路径
        /// </summary>
        /// <param name="strPath">指定的路径</param>
        /// <returns>绝对路径</returns>
        public static string GetMapPath(string strPath) {
            if (HttpContext.Current != null) {
                return HttpContext.Current.Server.MapPath(strPath);
            } else //非web程序引用
            {
                strPath = strPath.TrimStart('~');
                strPath = strPath.Replace("/", "\\");
                strPath = strPath.Replace("\\", "\\");
                if (strPath.StartsWith("\\")) {
                    strPath = strPath.TrimStart('\\');
                }
                return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath);
            }
        }
        #endregion

        #region 取得网站根目录的物理路径
        /// <summary>
        /// 取得网站根目录的物理路径
        /// </summary>
        public static string RootPhysicalPath {
            get {
                return System.Web.HttpContext.Current.Request.PhysicalApplicationPath;
            }
        }
        #endregion

        #region 时间相关

        /// <summary>
        /// 取得某月的第一天
        /// </summary>
        /// <param name="datetime">要取得月份第一天的时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day);
        }

        //// <summary>
        /// 取得某月的最后一天
        /// </summary>
        /// <param name="datetime">要取得月份最后一天的时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day).AddMonths(1).AddDays(-1);
        }

        /// <summary>
        /// 取得上个月第一天
        /// </summary>
        /// <param name="datetime">要取得上个月第一天的当前时间</param>
        /// <returns></returns>
        public static DateTime FirstDayOfPreviousMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day).AddMonths(-1);
        }

        /// <summary>
        /// 取得上个月的最后一天
        /// </summary>
        /// <param name="datetime">要取得上个月最后一天的当前时间</param>
        /// <returns></returns>
        public static DateTime LastDayOfPrdviousMonth(DateTime datetime)
        {
            return datetime.AddDays(1 - datetime.Day).AddDays(-1);
        }

        /// <summary> 
        /// 取指定日期是一年中的第几周 
        /// </summary> 
        /// <param name="dtime">给定的日期</param> 
        /// <returns>数字 一年中的第几周</returns> 
        public static int WeekOfYear(DateTime dtime) {
            GregorianCalendar gc = new GregorianCalendar();
            return gc.GetWeekOfYear(dtime, CalendarWeekRule.FirstDay, DayOfWeek.Monday);

        }
        /// <summary>
        /// 获取某一年有多少周
        /// </summary>
        /// <param name="year">年份</param>
        /// <returns>该年周数</returns>
        public static int GetWeekAmount(int year) {
            DateTime end = new DateTime(year, 12, 31);  //该年最后一天
            GregorianCalendar gc = new GregorianCalendar();
            return gc.GetWeekOfYear(end, CalendarWeekRule.FirstDay, DayOfWeek.Monday);  //该年星期数
        }

        /// <summary>
        /// 时间单位枚举
        /// </summary>
        public enum DateInterval {
            Second, Minute, Hour, Day, Week, Month, Quarter, Year
        }

        /// <summary>
        /// 获取两个日期直接的差
        /// </summary>
        /// <param name="Interval">时间单位枚举</param>
        /// <param name="StartDate">开始日期</param>
        /// <param name="EndDate">结束日期</param>
        /// <returns></returns>
        public static long DateDiff(DateInterval Interval, DateTime StartDate, DateTime EndDate) {
            long lngDateDiffValue = 0;
            System.TimeSpan TS = new System.TimeSpan(EndDate.Ticks - StartDate.Ticks);
            switch (Interval) {
                case DateInterval.Second:
                    lngDateDiffValue = (long)TS.TotalSeconds;
                    break;
                case DateInterval.Minute:
                    lngDateDiffValue = (long)TS.TotalMinutes;
                    break;
                case DateInterval.Hour:
                    lngDateDiffValue = (long)TS.TotalHours;
                    break;
                case DateInterval.Day:
                    lngDateDiffValue = (long)TS.Days;
                    break;
                case DateInterval.Week:
                    lngDateDiffValue = (long)(TS.Days / 7);
                    break;
                case DateInterval.Month:
                    lngDateDiffValue = (long)(TS.Days / 30);
                    break;
                case DateInterval.Quarter:
                    lngDateDiffValue = (long)((TS.Days / 30) / 3);
                    break;
                case DateInterval.Year:
                    lngDateDiffValue = (long)(TS.Days / 365);
                    break;
            }
            return (lngDateDiffValue);
        }
        #endregion

        #region Request操作
        /// <summary>
        /// 返回指定的服务器变量信息
        /// </summary>
        /// <param name="strName">服务器变量名</param>
        /// <returns>服务器变量信息</returns>
        public static string GetServerString(string strName) {
            //
            if (HttpContext.Current.Request.ServerVariables[strName] == null) {
                return "";
            }
            return HttpContext.Current.Request.ServerVariables[strName].ToString();
        }
        /// <summary>
        /// 得到当前完整主机头
        /// </summary>
        /// <returns></returns>
        public static string GetCurrentFullHost() {
            HttpRequest request = HttpContext.Current.Request;
            if (!request.Url.IsDefaultPort) {
                return string.Format("{0}:{1}", request.Url.Host, request.Url.Port.ToString());
            }
            return request.Url.Host;
        }
        /// <summary>
        /// 得到主机头
        /// </summary>
        /// <returns></returns>
        public static string GetHost() {
            return HttpContext.Current.Request.Url.Host;
        }
        /// <summary>
        /// 获取当前请求的原始 URL(URL 中域信息之后的部分,包括查询字符串(如果存在))
        /// </summary>
        /// <returns>原始 URL</returns>
        public static string GetRawUrl() {
            return HttpContext.Current.Request.RawUrl;
        }
        public static string CombineRawUrl(string url) {
            if ((url[0] != '~') && (url.IndexOf(':') < 0)) {
                string rawUrl = HttpContext.Current.Request.RawUrl;
                if (rawUrl.IndexOf('?') > 0) {
                    rawUrl = rawUrl.Split(new char[] { '?' })[0];
                }
                if (url.IndexOf('?') > 0) {
                    string[] strArray = url.Split(new char[] { '?' });
                    url = VirtualPathUtility.Combine(rawUrl, strArray[0]) + "?" + strArray[1];
                    return url;
                }
                url = VirtualPathUtility.Combine(rawUrl, url);
            }
            return url;
        }
        /// <summary>
        /// 判断当前访问是否来自浏览器软件
        /// </summary>
        /// <returns>当前访问是否来自浏览器软件</returns>
        public static bool IsBrowserGet() {
            string[] BrowserName = { "ie", "opera", "netscape", "mozilla", "konqueror", "firefox" };
            string curBrowser = HttpContext.Current.Request.Browser.Type.ToLower();
            for (int i = 0; i < BrowserName.Length; i++) {
                if (curBrowser.IndexOf(BrowserName[i]) >= 0) {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 判断是否来自搜索引擎链接
        /// </summary>
        /// <returns>是否来自搜索引擎链接</returns>
        public static bool IsSearchEnginesGet() {
            string[] SearchEngine = { "google", "yahoo", "msn", "baidu", "sogou", "sohu", "sina", "163", "lycos", "tom", "yisou", "iask", "soso", "gougou", "zhongsou" };
            string tmpReferrer = HttpContext.Current.Request.UrlReferrer.ToString().ToLower();
            for (int i = 0; i < SearchEngine.Length; i++) {
                if (tmpReferrer.IndexOf(SearchEngine[i]) >= 0) {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 获得当前完整Url地址
        /// </summary>
        /// <returns>当前完整Url地址</returns>
        public static string GetUrl() {
            return HttpContext.Current.Request.Url.ToString();
        }
        /// <summary>
        /// 获得指定Url参数的值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <returns>Url参数的值</returns>
        public static string GetQueryString(string strName) {
            if (HttpContext.Current.Request.QueryString[strName] == null) {
                return "";
            }
            return HttpContext.Current.Request.QueryString[strName];
        }
        /// <summary>
        /// 获得当前页面的名称
        /// </summary>
        /// <returns>当前页面的名称</returns>
        public static string GetPageName() {
            string[] urlArr = HttpContext.Current.Request.Url.AbsolutePath.Split('/');
            return urlArr[urlArr.Length - 1].ToLower();
        }
        /// <summary>
        /// 返回表单或Url参数的总个数
        /// </summary>
        /// <returns></returns>
        public static int GetParamCount() {
            return HttpContext.Current.Request.Form.Count + HttpContext.Current.Request.QueryString.Count;
        }
        /// <summary>
        /// 获得指定表单参数的值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <returns>表单参数的值</returns>
        public static string GetFormString(string strName) {
            if (HttpContext.Current.Request.Form[strName] == null) {
                return "";
            }
            return HttpContext.Current.Request.Form[strName];
        }
        /// <summary>
        /// 获得Url或表单参数的值, 先判断Url参数是否为空字符串, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">参数</param>
        /// <returns>Url或表单参数的值</returns>
        public static string GetString(string strName) {
            if ("".Equals(GetQueryString(strName))) {
                return GetFormString(strName);
            } else {
                return GetQueryString(strName);
            }
        }

        /// <summary>
        /// 获得指定Url参数的int类型值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url参数的int类型值</returns>
        public static int GetQueryInt(string strName, int defValue = 0) {
            return DataConvert.StrToInt(HttpContext.Current.Request.QueryString[strName], defValue);
        }
        /// <summary>
        /// 获得指定Url参数的long类型值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url参数的int类型值</returns>
        public static long GetQueryLong(string strName, long defValue = 0) {
            return DataConvert.StrToLong(HttpContext.Current.Request.QueryString[strName], defValue);
        }
        /// <summary>
        /// 获得指定表单参数的int类型值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>表单参数的int类型值</returns>
        public static int GetFormInt(string strName, int defValue = 0) {
            return DataConvert.StrToInt(HttpContext.Current.Request.Form[strName], defValue);
        }
        /// <summary>
        /// 获得指定表单参数的long类型值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>表单参数的long类型值</returns>
        public static long GetFormLong(string strName, long defValue = 0) {
            return DataConvert.StrToLong(HttpContext.Current.Request.Form[strName], defValue);
        }
        /// <summary>
        /// 获得指定Url或表单参数的long类型值, 先判断Url参数是否为缺省值, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">Url或表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url或表单参数的long类型值</returns>
        public static long GetLong(string strName, long defValue = 0) {
            if (GetQueryLong(strName, defValue) == defValue) {
                return GetFormLong(strName, defValue);
            } else {
                return GetQueryLong(strName, defValue);
            }
        }
        /// <summary>
        /// 获得指定Url或表单参数的int类型值, 先判断Url参数是否为缺省值, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">Url或表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url或表单参数的int类型值</returns>
        public static int GetInt(string strName, int defValue = 0) {
            if (GetQueryInt(strName, defValue) == defValue) {
                return GetFormInt(strName, defValue);
            } else {
                return GetQueryInt(strName, defValue);
            }
        }
        /// <summary>
        /// 获得指定Url参数的float类型值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url参数的int类型值</returns>
        public static float GetQueryFloat(string strName, float defValue = 0) {
            return DataConvert.StrToFloat(HttpContext.Current.Request.QueryString[strName], defValue);
        }
        /// <summary>
        /// 获得指定表单参数的float类型值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>表单参数的float类型值</returns>
        public static float GetFormFloat(string strName, float defValue = 0) {
            return DataConvert.StrToFloat(HttpContext.Current.Request.Form[strName], defValue);
        }
        /// <summary>
        /// 获得指定Url或表单参数的float类型值, 先判断Url参数是否为缺省值, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">Url或表单参数</param>
        /// <param name="defValue">缺省值 不传默认为0</param>
        /// <returns>Url或表单参数的int类型值</returns>
        public static float GetFloat(string strName, float defValue = 0) {
            if (GetQueryFloat(strName, defValue) == defValue) {
                return GetFormFloat(strName, defValue);
            } else {
                return GetQueryFloat(strName, defValue);
            }
        }

        /// <summary>
        /// 客户端IP地址，如果获取不到返回 0.0.0.0
        /// </summary>
        public static string ClientIP {
            get {
                var context = HttpContext.Current;
                string result = context.Request.UserHostAddress;
                if (string.IsNullOrEmpty(result)) {
                    result = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                }
                if (string.IsNullOrEmpty(result)) {
                    result = context.Request.ServerVariables["REMOTE_ADDR"];
                }
                if (string.IsNullOrEmpty(result)) {
                    result = context.Request.UserHostAddress;
                }
                return result;
            }
        }
        public static bool IsLanIP(string IP) {
            var result = false;
            var ips = new List<string>() { "10.", "192.", "172.", "127.", "::1", "localhost" };
            ips.ForEach(x => {
                if (IP.StartsWith(x)) result = true;
            });
            return result;
        }
        /// <summary>
        /// 客户端主机名称
        /// </summary>
        public static string ClientHostName {
            get {
                var context = HttpContext.Current;
                string IP = context.Request.UserHostAddress;
                string Name = context.Request.UserHostName;

                if (Name == IP || Name == "127.0.0.1" || Name == "::1") {
                    Name = context.Request.ServerVariables["REMOTE_HOST"];
                }
                if (Name == IP || Name == "127.0.0.1" || Name == "::1") {
                    try { Name = Dns.GetHostEntry(IP).HostName; } catch { }
                }
                return Name;
            }
        }
        /// <summary>
        /// 获取Form的参数和值拼接后的字段串
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetFormString(HttpContext context) {
            string re = context.Request.Form.ToString();
            return re;
        }
        /// <summary>
        /// 获取request的参数和值拼接后的字段串
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetQueryString(HttpContext context) {
            string re = context.Request.QueryString.ToString();
            return re;
        }
        /// <summary>
        /// 返回 URL 字符串的编码结果
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>编码结果</returns>
        public static string UrlEncode(string str) {
            return HttpUtility.UrlEncode(str);
        }
        /// <summary>
        /// 返回 URL 字符串的编码结果
        /// </summary>
        /// <param name="str">字符串</param>
        /// <returns>解码结果</returns>
        public static string UrlDecode(string str) {
            return HttpUtility.UrlDecode(str);
        }
        #endregion

        #region Session操作
        /// <summary>
        /// 读Session值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <returns>Session值</returns>
        public static string GetSession(string strName) {
            if (HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session[strName] != null) {
                string value = HttpContext.Current.Session[strName].ToString();
                return value;
            }
            return WriteSession(strName, "");
        }
        /// <summary>
        /// 写入Session值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <returns>Session值</returns>
        public static string WriteSession(string strName, string value) {
            if (HttpContext.Current == null) {
                return "";
            }
            HttpContext.Current.Session[strName] = value;
            return value;
        }
        /// <summary>
        /// 清除Session
        /// </summary>
        /// <param name="name">name of Session</param>
        public static void RemoveSession(string name) {
            if (HttpContext.Current.Session[name] != null) {
                HttpContext.Current.Session.Remove(name);
            }
        }
        /// <summary>
        ///  读Session值
        /// </summary>
        /// <param name="strName">名称</param>
        /// <param name="defaultValue">缺省值</param>
        /// <returns>Session值</returns>
        public static int GetSessionInt(string strName, int defaultValue) {
            if (HttpContext.Current != null && HttpContext.Current.Session != null && HttpContext.Current.Session[strName] != null) {
                return DataConvert.StrToInt(HttpContext.Current.Session[strName]);
            }

            return defaultValue;
        }
        #endregion
    }
}
